package tech.xs.workflow.service.impl;

import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import tech.xs.common.framework.service.CrudServiceImpl;
import tech.xs.workflow.bpmn.element.BpmnBaseElement;
import tech.xs.workflow.bpmn.element.ProcessElement;
import tech.xs.workflow.bpmn.element.SequenceFlowElement;
import tech.xs.workflow.bpmn.element.event.BaseEventElement;
import tech.xs.workflow.dao.BpmnSequenceFlowDao;
import tech.xs.workflow.domain.entity.BpmnProcess;
import tech.xs.workflow.domain.entity.BpmnSequenceFlow;
import tech.xs.workflow.domain.enums.BpmnNodeTypeEnum;
import tech.xs.workflow.service.BpmnSequenceFlowService;

import java.util.ArrayList;
import java.util.List;

@Service
public class BpmnSequenceFlowServiceImpl extends CrudServiceImpl<BpmnSequenceFlowDao, BpmnSequenceFlow> implements BpmnSequenceFlowService {
    @Override
    public void importSequenceFlow(BpmnProcess process, ProcessElement processElement) {
        List<SequenceFlowElement> sequenceFlows = processElement.getSequenceFlows();
        if (sequenceFlows == null) {
            return;
        }
        List<BpmnSequenceFlow> sequenceFlowList = new ArrayList<>();
        for (SequenceFlowElement item : sequenceFlows) {
            BpmnSequenceFlow bpmnSequenceFlow = new BpmnSequenceFlow();
            bpmnSequenceFlow.setProcessId(process.getId());
            bpmnSequenceFlow.setNodeId(item.getId());
            bpmnSequenceFlow.setName(item.getName());
            bpmnSequenceFlow.setSourceRef(item.getSourceRef());
            bpmnSequenceFlow.setTargetRef(item.getTargetRef());

            List<BpmnBaseElement> nodes = new ArrayList<>();
            nodes.addAll(processElement.getEvents());
            bpmnSequenceFlow.setSourceNodeType(getBpmnNodeType(item.getSourceRef(), nodes));
            bpmnSequenceFlow.setTargetNodeType(getBpmnNodeType(item.getTargetRef(), nodes));
            sequenceFlowList.add(bpmnSequenceFlow);
        }
        if (!sequenceFlowList.isEmpty()) {
            saveBatch(sequenceFlowList);
        }
    }


    private BpmnNodeTypeEnum getBpmnNodeType(String nodeId, List<BpmnBaseElement> nodes) {
        if (StrUtil.isBlank(nodeId)) {
            return null;
        }
        if (nodes == null) {
            return null;
        }
        for (BpmnBaseElement node : nodes) {
            if (nodeId.equals(node.getId())) {
                if (node instanceof BaseEventElement) {
                    return BpmnNodeTypeEnum.EVENT;
                }
            }
        }
        return null;
    }

}
